#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "demo.h"


enum
{
  CLASS_COL,
  NAME_COL,
  MAX_COL
};

typedef struct 
{
  gchar *clazz;
  gchar *name;
} NodeInfo;

static const NodeInfo node_infos[] = {
  {NULL, "living"},
  {"living", "animal"},
  {"living", "plant"},
  {"animal", "cat"},
  {"animal", "dog"},
  {"animal", "mouse"},
  {"plant", "apple"},
  {"plant", "rose"},
  {"plant", "oak"},
};



typedef struct 
{
  gboolean is_found; 
  GtkTreeIter *iter;
  gchar* clazz;
} FindClassData;

static gboolean find_class_cb(GtkTreeModel *model,
                            GtkTreePath *path,
                            GtkTreeIter *iter,
                            gpointer data)
{
  FindClassData *p = data;

  p->is_found = FALSE;

  gchar *clazz;
  gtk_tree_model_get(model, iter, NAME_COL, &clazz, -1);
  if(!g_strcmp0(clazz, p->clazz))
  {
    *p->iter = *iter;
    p->is_found = TRUE;
  }
  g_free(clazz);

  return p->is_found;   //FALSE, continue to search.
}

#if 1
static GtkTreeModel *create_model()
{
  GtkTreeStore *store;
  gint i;

  store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);

  for (i = 0; i < G_N_ELEMENTS(node_infos); i++)
  {
    const NodeInfo* p = &node_infos[i];
    GtkTreeIter iter;

    if(p->clazz)
    {
      //find class node
      FindClassData d;      
      d.iter = &iter;
      d.clazz = p->clazz;
      gtk_tree_model_foreach(GTK_TREE_MODEL(store), find_class_cb, &d);
      g_assert(d.is_found);

      //append node
      gtk_tree_store_append(store, &iter, d.iter);

      gtk_tree_store_set(store, &iter
                          , CLASS_COL, p->clazz
                          , NAME_COL, p->name
                          , -1
                          );
    }
    else
    {     //toplevel node
      gtk_tree_store_append(store, &iter, NULL);
      gtk_tree_store_set(store, &iter
                          , CLASS_COL, "(NULL)"
                          , NAME_COL, p->name
                          , -1
                          );
    }

  }


  return GTK_TREE_MODEL (store);
}

#else
static void fill_model(GtkTreeStore *store)
{
  // GtkTreeStore *store;
  gint i;

  // store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);

  for (i = 0; i < G_N_ELEMENTS(node_infos); i++)
  {
    const NodeInfo* p = &node_infos[i];
    GtkTreeIter iter;

    if(p->clazz)
    {
      //find class node
      FindClassData d;      
      d.iter = &iter;
      d.clazz = p->clazz;
      gtk_tree_model_foreach(GTK_TREE_MODEL(store), find_class_cb, &d);
      g_assert(d.is_found);

      //append node
      gtk_tree_store_append(store, &iter, d.iter);

      gtk_tree_store_set(store, &iter
                          , CLASS_COL, p->clazz
                          , NAME_COL, p->name
                          , -1
                          );
    }
    else
    {     //toplevel node
      gtk_tree_store_append(store, &iter, NULL);
      gtk_tree_store_set(store, &iter
                          , CLASS_COL, "(NULL)"
                          , NAME_COL, p->name
                          , -1
                          );
    }

  }
}
#endif




void do_treeview(GtkBox *parent)
{
    GtkWidget* frame;
    GtkWidget* vbox;
    GtkWidget* treeview;
    GtkTreeModel *model;
    GtkTreeViewColumn *column;    
    GtkCellRenderer *renderer;
    GtkTreeSelection *selection;


    frame = gtk_frame_new("treeview");
    gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
    gtk_box_pack_start(parent, frame, TRUE, TRUE, 0);

    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
    gtk_container_add(GTK_CONTAINER(frame), vbox);


#if 0
    model = GTK_TREE_MODEL(gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING));
    gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), model);
    fill_model(GTK_TREE_STORE(model));
#else
    model = create_model();      //unref in L168
#endif

    treeview = gtk_tree_view_new_with_model(model);

    
    //add columns

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes ("Class"
                                                        , renderer
                                                        , "text"      //关联GtkCellRendererText的'text' prop
                                                        , CLASS_COL
                                                        , NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes ("Name",
                                                        renderer,
                                                        "text", 
                                                        NAME_COL,
                                                        NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);



    // gtk_widget_set_halign (treeview, GTK_ALIGN_CENTER);
    // gtk_widget_set_valign (treeview, GTK_ALIGN_CENTER);
    gtk_box_pack_start(GTK_BOX(vbox), treeview, FALSE, FALSE, 5);

    //selection mode
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (treeview));
    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);

    //select the first node
    GtkTreeIter iter;
    gtk_tree_model_get_iter_first(model, &iter);
    gtk_tree_selection_select_iter(selection, &iter);

    g_object_unref (model);                         //GtkListStore不是GInitiallyUnowned, 没有sink机制. 故需unref

    gtk_widget_show_all(GTK_WIDGET(parent));    
}